#!/usr/bin/ruby
# -*- ruby -*-
#
# http://www.reddit.com/r/dailyprogrammer/comments/1q6pq5/11413_challenge_140_easy_variable_notation/

class Processor
  def separator
  end

  def transform_token(word)
    return word
  end

  def post_process(joined)
    return joined
  end

  def input(str)
    raise "Implement me"
  end

  def output(tokens)
    return post_process(tokens.map { |t| transform_token(t) }.join(separator))
  end
end

class CamelCaseProcessor < Processor
  def separator
    return ''
  end

  def post_process(joined)
    return joined[0, 1].downcase + joined[1 .. -1]
  end

  def transform_token(token)
    return token.capitalize
  end

  def input(str)
    last = nil

    tokens = []

    str.split(//).each_with_index do |c, i|
      if /[A-Z]/.match(c)
        tokens << str[(last.nil? ? 0 : last) .. i - 1]

        last = i
      end
    end

    tokens << str[(last.nil? ? 0 : last) .. str.length]

    return tokens
  end
end

class SnakeCaseProcessor < Processor
  def separator
    return '_'
  end

  def transform_token(token)
    return token.downcase
  end

  def input(str)
    return str.split('_')
  end
end

class UpperSnakeCaseProcessor < SnakeCaseProcessor
  def transform_token(token)
    return token.upcase
  end

  def input(str)
    return str.split('_')
  end
end

def input(source, str)
  case source
  when "0"
    return CamelCaseProcessor.new.input(str)
  when "1"
    return SnakeCaseProcessor.new.input(str)
  when "2"
    return UpperSnakeCaseProcessor.new.input(str)
  else
    raise "Unknown source format #{source}"
  end
end

def output(destination, tokens)
  case destination
  when "0"
    return CamelCaseProcessor.new.output(tokens)
  when "1"
    return SnakeCaseProcessor.new.output(tokens)
  when "2"
    return UpperSnakeCaseProcessor.new.output(tokens)
  else
    raise "Unknown destination format #{destination}"
  end
end

source = ARGV.shift
destination = ARGV.shift
str = ARGV.shift

tokens = input(source, str)
puts output(destination, tokens)
